home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / cdity / MRQ.lha / MRQ / Source / RCS / mrq.c < prev    next >
C/C++ Source or Header  |  2000-10-16  |  24KB  |  888 lines

  1. head    1.4;
  2. access;
  3. symbols;
  4. locks
  5.     msbethke:1.4; strict;
  6. comment    @ * @;
  7.  
  8.  
  9. 1.4
  10. date    2000.03.30.23.17.52;    author msbethke;    state Exp;
  11. branches;
  12. next    1.3;
  13.  
  14. 1.3
  15. date    2000.02.16.18.25.42;    author msbethke;    state Exp;
  16. branches;
  17. next    1.2;
  18.  
  19. 1.2
  20. date    2000.01.25.17.28.05;    author msbethke;    state Exp;
  21. branches;
  22. next    1.1;
  23.  
  24. 1.1
  25. date    2000.01.25.16.43.18;    author msbethke;    state Exp;
  26. branches;
  27. next    ;
  28.  
  29.  
  30. desc
  31. @MRQ - The MUI ReQuester improver
  32. Started using RCS for V2.0
  33. @
  34.  
  35.  
  36. 1.4
  37. log
  38. @Changed NewImage.mcc -> Guigfx.mcc
  39. @
  40. text
  41. @/* mrq.c
  42. ** Main program source for MRQ, the MUI Requester Improver
  43. **
  44. ** ©1997-2000 by Matthias.Bethke <Matthias.Bethke@@gmx.net>
  45. ** You are free to modify this source or use parts of it in your
  46. ** own programs as long as they are distributed as freeware.
  47. */
  48.  
  49. /* $Id: mrq.c 1.3 2000/02/16 18:25:42 msbethke Exp msbethke $
  50. **
  51. ** $Log: mrq.c $
  52. ** Revision 1.3  2000/02/16 18:25:42  msbethke
  53. ** Disabled DOS requesters for MRQ's main process to avoid deadlocks
  54. **
  55. ** Revision 1.2  2000/01/25 17:28:05  msbethke
  56. ** Adapted to new header names
  57. **
  58. ** Revision 1.1  2000/01/25 16:43:18  msbethke
  59. ** Initial revision
  60. **
  61. */
  62.  
  63. #include <proto/icon.h>
  64. #include <proto/intuition.h>
  65. #include <proto/rexxsyslib.h>
  66. #include <proto/commodities.h>
  67. #include <proto/datatypes.h>
  68. #include <proto/wbstart.h>
  69. #include <clib/debug_protos.h>
  70. #include <libraries/reqtools.h>
  71. #include <guigfx/guigfx.h>
  72. #include <exec/memory.h>
  73. #include <dos/dostags.h>
  74. #include <lib/mb_utils.h>
  75. #include <MUI/Guigfx_mcc.h>
  76. #include <dos.h>
  77. #include <stdarg.h>
  78. #include <string.h>
  79. #include <stdlib.h>
  80. #include <ctype.h>
  81. #include "mrq.h"
  82. #include "config.h"
  83. #include "mui_macros.h"
  84. #include "muistuff.h"
  85. #include "Requesters.h"
  86. #include "MRQasm.h"
  87. #include "mrqwindowclass.h"
  88.  
  89. #define RTEZREQUESTA_OFFSET (-66)
  90. #define EASYREQUESTARGS_OFFSET (-588)
  91.  
  92. #define GUIGFXLIB_NAME "guigfx.library"
  93. #define GUIGFXLIB_VMIN 15
  94. #define REQTOOLSLIB_NAME "reqtools.library"
  95. #define REQTOOLSLIB_VMIN 0
  96. #define CGFXLIB_NAME "cybergraphics.library"
  97. #define CGFXLIB_VMIN 0
  98.  
  99. /*************************************************************************/
  100. /* local protos & dummy functions                                        */
  101. /*************************************************************************/
  102. static BOOL OpenLibs(void);
  103. static void CloseLibs(void);
  104. static BOOL BuildApp(void);
  105. static void DisposeApp(APTR app);
  106. static APTR ReadToolTypes(struct WBStartup*);
  107. static APTR ReadShellParams(void);
  108. static STRPTR FindConfigFile(void);
  109. static BOOL CheckDir(STRPTR);
  110. static BOOL AskQuit(void);
  111. static BOOL CheckPatchManager(void);
  112. static LONG DecodeQuality(STRPTR);
  113. static void StartExternalProgram(STRPTR);
  114. static BOOL ExistsIcon(STRPTR);
  115. static BOOL CreateCustomClasses(void);
  116. static void DeleteCustomClasses(void);
  117. /* dummies */
  118. void __regargs _CXBRK(void) {}
  119. void chkabort(void) {}
  120.  
  121.  
  122. /*************************************************************************/
  123. /* global identifiers                                                    */
  124. /*************************************************************************/
  125. APTR OldEasyRequestArgs, OldrtEZRequestA, Application;
  126. struct MUI_CustomClass *MUIMRQWindowClass;
  127. struct IClass *MRQWindowClass;
  128. UBYTE ProgName[80]={0};
  129. struct TTVars ttVars = {0};
  130. struct MRQConfig *Config;
  131. const UBYTE VersionString[]="$VER: MRQ 2.0b5 by M.Bethke (30.03.2000)";
  132. struct Library *MUIMasterBase, *GuiGFXBase, *CyberGfxBase;
  133. struct ReqToolsBase *ReqToolsBase;
  134. struct MsgPort *MainPort;
  135. LONG AppActive=TRUE;
  136. LONG __stack = 12288;
  137. BPTR _debugfh=NULL;
  138. STRPTR true_s="TRUE", false_s="FALSE",
  139.          none_s="<none>", unset_s="<unset>";    // take some work off the stringmerger
  140. /*************************************************************************/
  141. /* hooks                                                                 */
  142. /*************************************************************************/
  143. static void __saveds __asm __interrupt BrokerHookFunc(register __a1 CxMsg*, register __a2 APTR);
  144. struct Hook BrokerHook = {{NULL,NULL},(void*)(&BrokerHookFunc),NULL,NULL};
  145.  
  146.  
  147.  
  148. /*************************************************************************/
  149.  
  150. LONG main(int argc, char *argv[])
  151. {
  152. LONG rcode = RETURN_OK;
  153. APTR Args;
  154. STRPTR ConfigName;
  155. static const UBYTE MRQRendezvousPort[] = "MRQ.Rendezvous";
  156. struct Process *MyProc;
  157. APTR MyWindowPtr;
  158.  
  159.     if(!GetProgramName(ProgName,sizeof(ProgName))) strcpy(ProgName,"MRQ");
  160.  
  161.     MyProc = (struct Process*)FindTask(NULL);
  162.     MyWindowPtr = MyProc->pr_WindowPtr;
  163.     MyProc->pr_WindowPtr = (APTR)-1;
  164.  
  165.     if(FindPort((STRPTR)MRQRendezvousPort))
  166.     {
  167.         if(argc)
  168.         {
  169.             Printf("%s: already running!\n",*argv);
  170.         } else
  171.         {
  172.         struct EasyStruct es={sizeof(struct EasyStruct),0,"MRQ Error","Please don't start me twice!","I won't!"};
  173.  
  174.             EasyRequestArgs(NULL,&es,NULL,NULL);
  175.         }
  176.         return RETURN_WARN;
  177.     }
  178.  
  179.     if(argc)    Args = ReadShellParams();
  180.     else Args = ReadToolTypes((struct WBStartup*)argv);
  181.  
  182.     if(!Args) return RETURN_FAIL;
  183.  
  184.     if(!(ConfigName = FindConfigFile()))
  185.     {
  186.     struct EasyStruct es={sizeof(struct EasyStruct),0,"MRQ Error","Can't find config file!","I see"};
  187.  
  188.         EasyRequestArgs(NULL,&es,NULL,NULL);
  189.         if(argc) FreeArgs((struct RDArgs*)Args);
  190.         else FreeDiskObject((struct DiskObject*)Args);
  191.         return RETURN_ERROR;
  192.     }
  193.  
  194.     if(ttVars.DefImageDir == NULL || (!CheckDir(ttVars.DefImageDir)))
  195.     {
  196.         if(!CheckDir(ttVars.DefImageDir="PROGDIR:MRQ-images"))
  197.         {
  198.             if(!CheckDir(ttVars.DefImageDir="s:MRQ-images"))
  199.             {
  200.             struct EasyStruct es={sizeof(struct EasyStruct),0,"MRQ Error","Can't find image directory!","I see"};
  201.  
  202.                 EasyRequestArgs(NULL,&es,NULL,NULL);
  203.                 if(argc) FreeArgs((struct RDArgs*)Args);
  204.                 else FreeDiskObject((struct DiskObject*)Args);
  205.                 return RETURN_ERROR;
  206.             }
  207.         }
  208.     }
  209.  
  210.     if(ttVars.Debug)                                    // debug info wanted
  211.     {
  212.         if(!argc || strlen(ttVars.Debug))        // WB-start or file specified
  213.         {
  214.             _debugfh=Open(strlen(ttVars.Debug) ?
  215.                                 ttVars.Debug :                // file specified
  216.                                 (STRPTR)"CON:40/80/640/180/MRQ_CONSOLE",MODE_NEWFILE);    // default
  217.         } else
  218.         {
  219.             _debugfh = Output();                        // use stdout
  220.         }
  221.     }
  222.  
  223.     prdebug(    "Started %s\n\n"
  224.                 "Parameters read:\n\tCONFIGFILE    : %s\n\tMOUSEREQ      : %s\n\t"
  225.                 "SAMEWIDTH     : %s\n\tFRONTSCREEN   : %s\n\tTRANSPARENCY  : %s\n\t"
  226.                 "SINGLEFRAME   : %s\n\tSIZEABLE      : %s\n\tCENTERTEXT    : %s\n\t"
  227.                 "NORTPATCH     : %s\n\tIMAGES        : %s\n\t"
  228.                 "QUALITY       : %s\n\tIMG_YES       : %s\n\tIMG_NO        : %s\n\t"
  229.                 "IMG_CANCEL    : %s\n\tIBUTTONSBYTEXT: %s\n\tAFTERPATCH    : %s\n\t"
  230.                 "AVOIDTASKS    : %s\n\n",
  231.         VersionString+6,
  232.         ConfigName,
  233.         ttVars.MousedReq?true_s:false_s,
  234.         ttVars.SameWidthButtons?true_s:false_s,
  235.         ttVars.FrontmostScreen?true_s:false_s,
  236.         ttVars.Transparency?true_s:false_s,
  237.         ttVars.SingleFrame?true_s:false_s,
  238.         ttVars.Sizeable?true_s:false_s,
  239.         ttVars.Centered?true_s:false_s,
  240.         ttVars.NoRTPatch?true_s:false_s,
  241.         ttVars.DefImageDir,
  242.         (ttVars.Quality==MUIV_Guigfx_Quality_Best)?"Best":
  243.         (ttVars.Quality==MUIV_Guigfx_Quality_Medium)?"Medium":
  244.         (ttVars.Quality==MUIV_Guigfx_Quality_High)?"High":
  245.         "Low",
  246.         ttVars.IB_Yes?ttVars.IB_Yes:none_s,
  247.         ttVars.IB_No?ttVars.IB_No:none_s,
  248.         ttVars.IB_Cancel?ttVars.IB_Cancel:none_s,
  249.         ttVars.IButtonsByText?ttVars.IButtonsByText:unset_s,
  250.         ttVars.AfterPatch?ttVars.AfterPatch:unset_s,
  251.         ttVars.AvoidTasks?ttVars.AvoidTasks:unset_s
  252.         );
  253.  
  254.     if(OpenLibs())
  255.     {
  256.         if(Config = ReadMRQConfig(ConfigName))
  257.         {
  258.             if(MainPort = CreateMsgPort())
  259.             {
  260.                 MainPort->mp_Node.ln_Name = (STRPTR)MRQRendezvousPort;
  261.                 MainPort->mp_Node.ln_Pri = -128;
  262.                 AddPort(MainPort);
  263.  
  264.                 if(BuildApp())
  265.                 {
  266.                 ULONG sigs, result;
  267.                 BOOL running=TRUE;
  268.                 struct MsgPort *RexxRPort;
  269.         
  270.                     if(CreateCustomClasses())
  271.                     {
  272.                         if(RexxRPort = CreateMsgPort())
  273.                         {
  274.                         LONG RexxMPending=0,    RexxPortSignal, MainPortSignal;
  275.             
  276.                             RexxPortSignal = 1<<(RexxRPort->mp_SigBit);
  277.                             MainPortSignal = 1<<(MainPort->mp_SigBit);
  278.  
  279.                             OldEasyRequestArgs = SetFunction((struct Library*)IntuitionBase,EASYREQUESTARGS_OFFSET,(APTR)(&EasyRequestArgsPatch));
  280.                             prdebug("SetFunction() called on %s\n","intuition.library/EasyRequestArgs()");
  281.                             if(ReqToolsBase)                // obviously, only patch if RT found
  282.                             {
  283.                                 if(ttVars.NoRTPatch)        // if no reqtools patching desired
  284.                                 {
  285.                                     CloseLibrary((struct Library*)ReqToolsBase);    // close early
  286.                                     ReqToolsBase = NULL;
  287.                                 } else
  288.                                 {
  289.                                     OldrtEZRequestA = SetFunction((struct Library*)ReqToolsBase,RTEZREQUESTA_OFFSET,(APTR)(&rtEZRequestA_Wedge));
  290.                                     prdebug("SetFunction() called on %s\n","reqtools.library/rtEZRequestA()");
  291.                                 }
  292.                             }
  293.  
  294.                             if(ttVars.AfterPatch) StartExternalProgram(ttVars.AfterPatch);
  295.                             
  296.                             prdebug("Entering main loop\n\n");
  297.                             while(running)
  298.                             {
  299.                                 result = DoMethod(Application,MUIM_Application_NewInput,&sigs);
  300.             
  301.                                 switch(result)
  302.                                 {
  303.                                     case MUIV_Application_ReturnID_Quit :
  304.                                         running = !AskQuit();
  305.                                         break;
  306.             
  307.                                     default :
  308.                                         if(result && (!(result & 0x01)))
  309.                                         {
  310.                                         struct MRQReqMessage *msg;
  311.  
  312.                                             msg = (struct MRQReqMessage*)result;
  313.  
  314.                                             if(msg->mrm_EventHandler)
  315.                                             {
  316.                                                 DoMethod(msg->mrm_WindowObject,
  317.                                                             MUIM_Window_RemEventHandler,
  318.                                                             msg->mrm_EventHandler);
  319.                                             }
  320.                                             DoMethod(Application,OM_REMMEMBER,msg->mrm_WindowObject);
  321.                                             DisposeObject(msg->mrm_WindowObject);
  322.                                             ReplyMsg((struct Message*)msg);
  323.                                         }
  324.                                 }
  325.                                 if(sigs)
  326.                                 {
  327.                                     sigs = Wait(sigs | RexxPortSignal | MainPortSignal | SIGBREAKF_CTRL_C);
  328.  
  329.                                     if(sigs & SIGBREAKF_CTRL_C)    // got break signal
  330.                                     {
  331.                                         prdebug("Ctrl-C received\n");
  332.                                         running = FALSE;
  333.                                         continue;
  334.                                     }
  335.  
  336.                                     if(sigs & MainPortSignal)        // have to set up a new requester
  337.                                     {
  338.                                     struct MRQReqMessage *msg;
  339.  
  340.                                         if(!(msg = (struct MRQReqMessage*)GetMsg(MainPort)))
  341.                                         {
  342.                                             DisplayBeep(NULL);
  343.                                             continue;
  344.                                         }
  345.  
  346.                                         MUI_EasyRequestArgs(msg);        // setup the entire requester
  347.  
  348.                                         if(msg->mrm_FatalError)            // handle errors
  349.                                         {
  350.                                             ReplyMsg((struct Message*)msg);
  351.                                             continue;
  352.                                         }
  353.  
  354.                                         if(msg->mrm_ARexxCmd)            // have to dispatch an ARexx command
  355.                                         {
  356.                                         struct RexxMsg *rmsg;
  357.  
  358.                                             prdebug("Sending ARexx message:\n\tPORT: '%s'\n\tCMND: '%s'...",msg->mrm_ARexxPort,msg->mrm_ARexxCmd);
  359.         
  360.                                             if(rmsg = CreateRexxMsg(RexxRPort,NULL,msg->mrm_ARexxPort))
  361.                                             {
  362.                                                 rmsg->rm_Action    = RXCOMM;
  363.                                                 rmsg->rm_Args[0]    = msg->mrm_ARexxCmd;
  364.                                                 if(FillRexxMsg(rmsg,1,0))
  365.                                                 {
  366.                                                 struct MsgPort *RxDestPort;
  367.  
  368.                                                     Forbid();
  369.                                                     if(RxDestPort = FindPort(msg->mrm_ARexxPort))
  370.                                                     {
  371.                                                         PutMsg(RxDestPort,(struct Message*)rmsg);
  372.                                                         RexxMPending++;
  373.                                                         Permit();
  374.                                                         prdebug("OK!\n");
  375.                                                     } else
  376.                                                     {
  377.                                                         Permit();
  378.                                                         prdebug("port not found!\n");
  379.                                                     }
  380.                                                 } else prdebug("FillRexxMsg() failed!\n");
  381.                                             } else prdebug("can't create rexx message!\n");
  382.                                         }
  383.                                     }
  384.  
  385.                                     if(sigs & RexxPortSignal)        // got ARexx demon reply
  386.                                     {
  387.                                     struct RexxMsg *rmsg;
  388.             
  389.                                         while(rmsg = (struct RexxMsg*)GetMsg(RexxRPort))
  390.                                         {
  391.                                             ClearRexxMsg(rmsg,1);
  392.                                             DeleteRexxMsg(rmsg);
  393.                                             RexxMPending--;
  394.                                             prdebug("Rexxhost reply received\n");
  395.                                         }
  396.                                     }
  397.                                 }
  398.                             }
  399.  
  400.                             if(ReqToolsBase)
  401.                             {
  402.                                 SetFunction((struct Library*)ReqToolsBase,RTEZREQUESTA_OFFSET,OldrtEZRequestA);
  403.                                 prdebug("rtEZRequestA()-patch removed\n");
  404.                             }
  405.                             SetFunction((struct Library*)IntuitionBase,EASYREQUESTARGS_OFFSET,OldEasyRequestArgs);
  406.                             prdebug("EasyRequestArgs()-patch removed\n");
  407.                             while(RexxMPending)
  408.                             {
  409.                                 WaitPort(RexxRPort);
  410.                                 GetMsg(RexxRPort);
  411.                             }
  412.                             DeleteMsgPort(RexxRPort);
  413.                         } else
  414.                         {
  415.                             prdebug("Can't create ARexx communication port!\n");
  416.                             rcode=RETURN_FAIL;
  417.                         }
  418.                         DeleteCustomClasses();
  419.                     } else
  420.                     {
  421.                         prdebug("Can't create custom classes!\n");
  422.                         rcode=RETURN_FAIL;
  423.                     }
  424.                     DisposeApp(Application);        
  425.                     prdebug("Disposed of MUI app\n");
  426.                 } else
  427.                 {
  428.                     prdebug("Can't build MUI application object!\n");
  429.                     rcode=RETURN_FAIL;
  430.                 }
  431.                 RemPort(MainPort);
  432.                 DeleteMsgPort(MainPort);
  433.             }
  434.             FreeMRQConfig(Config);
  435.         } else rcode=RETURN_FAIL;
  436.         CloseLibs();
  437.     } else rcode=RETURN_FAIL;
  438.  
  439.     if(_debugfh)                                        // debug output being printed
  440.     {
  441.         if(strlen(ttVars.Debug) || !argc)        // file specified or WB-start
  442.             Close(_debugfh);
  443.     }
  444.  
  445.     if(argc) FreeArgs((struct RDArgs*)Args);
  446.     else FreeDiskObject((struct DiskObject*)Args);
  447.  
  448.     MyProc->pr_WindowPtr = MyWindowPtr;
  449.  
  450.     return rcode;
  451. }
  452.  
  453. /*************************************************************************/
  454.  
  455. static BOOL OpenLibs(void)
  456. {
  457. struct EasyStruct es={sizeof(struct EasyStruct),0,"MRQ Error","Can't open %s V%ld+!","Dammit!"};
  458.  
  459.     ReqToolsBase = (struct ReqToolsBase*)OpenLibrary(REQTOOLSLIB_NAME, REQTOOLSLIB_VMIN);    // optional
  460.     CyberGfxBase = OpenLibrary(CGFXLIB_NAME,CGFXLIB_VMIN);             // optional
  461.     if(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN))
  462.     {
  463.         if(GuiGFXBase = OpenLibrary(GUIGFXLIB_NAME,GUIGFXLIB_VMIN))
  464.         {
  465.             return TRUE;
  466.         } else
  467.         {
  468.             EasyRequest(NULL,&es,NULL,GUIGFXLIB_NAME,GUIGFXLIB_VMIN);
  469.             CloseLibs();
  470.         }
  471.     } else
  472.     {
  473.         EasyRequest(NULL,&es,NULL,MUIMASTER_NAME,MUIMASTER_VMIN);
  474.     }
  475.     return FALSE;    
  476. }
  477.  
  478. static void CloseLibs(void)
  479. {
  480.     if(MUIMasterBase) CloseLibrary(MUIMasterBase);
  481.     if(ReqToolsBase) CloseLibrary((struct Library*)ReqToolsBase);
  482. }
  483.  
  484. /*************************************************************************/
  485.  
  486. static BOOL BuildApp(void)
  487. {
  488.     Application = ApplicationObject,
  489.         MUIA_Application_Title      , "MRQ",
  490.         MUIA_Application_Version    , VersionString,
  491.         MUIA_Application_Copyright  , "Matthias Bethke",
  492.         MUIA_Application_Author     , "Matthias Bethke",
  493.         MUIA_Application_Description, "A requester replacement using MUI",
  494.         MUIA_Application_Base       , "MRQ",
  495.         MUIA_Application_SingleTask , TRUE,
  496.         MUIA_Application_BrokerHook , &BrokerHook,
  497.         End;
  498.  
  499.     if(Application)
  500.     {
  501.         DoMethod(Application,MUIM_Notify,MUIA_Application_Active,MUIV_EveryTime,
  502.                     MUIV_Notify_Self,3,MUIM_WriteLong,MUIV_TriggerValue,&AppActive);
  503.     }
  504.     return (BOOL)Application;
  505. }
  506.  
  507.  
  508. static void DisposeApp(APTR app)
  509. {
  510.     if(app) MUI_DisposeObject(app);
  511. }
  512.  
  513. /*************************************************************************/
  514.  
  515. static APTR ReadToolTypes(struct WBStartup *msg)
  516. {
  517. struct DiskObject *dob;
  518. BPTR olddir=0, homedir;
  519.  
  520.     if(!(msg->sm_NumArgs)) return NULL;
  521.     homedir = msg->sm_ArgList[0].wa_Lock;
  522.     if(homedir) olddir = CurrentDir(homedir);
  523.  
  524.     if(dob = GetDiskObject(msg->sm_ArgList[0].wa_Name))
  525.     {
  526.         ttVars.ConfigName            = FindToolType(dob->do_ToolTypes,"CONFIGFILE");
  527.         ttVars.Debug                = FindToolType(dob->do_ToolTypes,"DEBUG");
  528.         ttVars.MousedReq            = (LONG)FindToolType(dob->do_ToolTypes,"MOUSEREQ");
  529.         ttVars.SameWidthButtons    = (LONG)FindToolType(dob->do_ToolTypes,"SAMEWIDTH");
  530.         ttVars.FrontmostScreen    = (LONG)FindToolType(dob->do_ToolTypes,"FRONTSCREEN");
  531.         ttVars.SingleFrame        = (LONG)FindToolType(dob->do_ToolTypes,"SINGLEFRAME");
  532.         ttVars.Transparency        = (LONG)FindToolType(dob->do_ToolTypes,"TRANSPARENCY");
  533.         ttVars.Sizeable            = (LONG)FindToolType(dob->do_ToolTypes,"SIZEABLE");
  534.         ttVars.Centered            = (LONG)FindToolType(dob->do_ToolTypes,"CENTERTEXT");
  535.         ttVars.NoRTPatch            = (LONG)FindToolType(dob->do_ToolTypes,"NORTPATCH");
  536.         ttVars.DefaultIcon        = (LONG)FindToolType(dob->do_ToolTypes,"DEFAULTICON");
  537.         ttVars.DefImageDir        = FindToolType(dob->do_ToolTypes,"IMAGES");
  538.         ttVars.IButtonsByText    = FindToolType(dob->do_ToolTypes,"IBUTTONSBYTEXT");
  539.         ttVars.IB_Yes                = FindToolType(dob->do_ToolTypes,"IMG_YES");
  540.         ttVars.IB_No                = FindToolType(dob->do_ToolTypes,"IMG_NO");
  541.         ttVars.IB_Cancel            = FindToolType(dob->do_ToolTypes,"IMG_CANCEL");
  542.         ttVars.AfterPatch            = FindToolType(dob->do_ToolTypes,"AFTERPATCH");
  543.         ttVars.AvoidTasks            = FindToolType(dob->do_ToolTypes,"AVOIDTASKS");
  544.  
  545.         ttVars.Quality                = DecodeQuality(FindToolType(dob->do_ToolTypes,"QUALITY"));
  546.     } else PrintFault(IoErr(),ProgName);
  547.     if(olddir) CurrentDir(olddir);
  548.     return (APTR)dob;
  549. }
  550.  
  551. static APTR ReadShellParams(void)
  552. {
  553. struct RDArgs *Args;
  554. struct MRQShellArguments args={0};
  555.  
  556.     if(Args = ReadArgs(
  557.         "Configfile,IMD=ImageDir/K,BY=Button_Yes/K,BN=Button_No/K,BC=Button_Cancel/K,"
  558.         "IBBT=IButtonsByText/K,QU=Quality/K,AT=AvoidTasks/K,DI=DefaultIcon/S"
  559.         "MR=MouseReq/S,SW=SameWidth/S,FS=FrontScreen/S,"
  560.         "SF=SingleFrame/S,TR=Transparency/S,SI=Sizeable/S,CT=CenterText/S,NRTP=NoRTPatch/S,"
  561.         "AP=AfterPatch/K,Debug/K",(LONG*)&args,NULL))
  562.     {
  563.         ttVars.ConfigName        = args.ConfigName;    // may be NULL!
  564.  
  565.         ttVars.DefImageDir    = args.DefImageDir    ? args.DefImageDir    : NULL;
  566.         ttVars.IB_Yes            = args.IB_Yes            ? args.IB_Yes            : NULL;
  567.         ttVars.IB_No            = args.IB_No            ? args.IB_No            : NULL;
  568.         ttVars.IB_Cancel        = args.IB_Cancel        ? args.IB_Cancel        : NULL;
  569.         ttVars.IButtonsByText= args.IButtonsByText? args.IButtonsByText: NULL;
  570.  
  571.         ttVars.Quality        = DecodeQuality(args.Quality);
  572.  
  573.         ttVars.MousedReq            = args.MousedReq;
  574.         ttVars.SameWidthButtons    = args.SameWidth;
  575.         ttVars.FrontmostScreen    = args.FrontScreen;
  576.         ttVars.SingleFrame        = args.SingleFrame;
  577.         ttVars.Transparency        = args.Transparency;
  578.         ttVars.Sizeable            = args.Sizeable;
  579.         ttVars.Centered            = args.Centered;
  580.         ttVars.NoRTPatch            = args.NoRTPatch;
  581.         ttVars.AfterPatch            = args.AfterPatch;
  582.         ttVars.Debug                = args.Debug;
  583.         ttVars.AvoidTasks            = args.AvoidTasks;
  584.         ttVars.DefaultIcon        = args.DefaultIcon;
  585.     } else PrintFault(IoErr(),ProgName);
  586.     return (APTR)Args;
  587. }
  588.  
  589. /*************************************************************************/
  590.  
  591. static void __saveds __asm __interrupt BrokerHookFunc(register __a1 CxMsg *cxm, register __a2 APTR app)
  592. {
  593.     if(CxMsgType(cxm) == CXM_COMMAND)
  594.     {
  595.         if(CxMsgID(cxm) == CXCMD_APPEAR)
  596.         {
  597.             if(MUI_RequestA(Application,NULL,0,"MRQ Request","*_MUIprefs|_Configfile",
  598.                                     "Edit MUI settings for MRQ\nor edit the configfile?",
  599.                                     NULL))
  600.             {
  601.                 DoMethod(app,MUIM_Application_OpenConfigWindow,0);
  602.             } else prdebug("Configfile editing not yet implemented!\n");
  603.         }
  604.     }
  605. }
  606.  
  607. /*************************************************************************/
  608.  
  609.  
  610. static LONG DecodeQuality(STRPTR s)
  611. {
  612.     if(s)
  613.     {
  614.         if(!stricmp(s,"best")) return MUIV_Guigfx_Quality_Best;
  615.         if(!stricmp(s,"high")) return MUIV_Guigfx_Quality_High;
  616.         if(!stricmp(s,"low")) return MUIV_Guigfx_Quality_Low;
  617.     }
  618.     return MUIV_Guigfx_Quality_Medium;        // default
  619. }
  620.  
  621.  
  622. /*************************************************************************/
  623.  
  624. static void StartExternalProgram(STRPTR ttype)
  625. {
  626. BPTR FileLock;
  627. BOOL WBStarted=FALSE;
  628.  
  629.     if(FileLock = Lock(ttype,ACCESS_READ))
  630.     {
  631.     BPTR DirLock;
  632.  
  633.         DirLock = ParentDir(FileLock);
  634.         UnLock(FileLock);
  635.         if(ExistsIcon(ttype))
  636.         {
  637.         struct Library *WBStartBase;
  638.  
  639.             if(WBStartBase = OpenLibrary("wbstart.library",0))
  640.             {
  641.                 prdebug("Starting Workbench program '%s'\n",ttype);
  642.  
  643.                 if(WBStartTags(WBStart_Name, ttype,
  644.                                     WBStart_DirectoryLock, DirLock,
  645.                                     TAG_DONE) == RETURN_OK)
  646.                 {
  647.                     WBStarted = TRUE;
  648.                 } else
  649.                 {
  650.                     prdebug("Error starting program!\n");
  651.                 }
  652.                 CloseLibrary(WBStartBase);
  653.             } else prdebug("Starting Workbench programs requires %s\n","wbstart.library");
  654.         }
  655.     }
  656.  
  657.     if(!WBStarted)
  658.     {
  659.     STRPTR tt,prog,args;
  660.  
  661.         if(tt = AllocVecPooled(Config->mc_MemPool,strlen(ttype)+1))
  662.         {
  663.             strcpy(tt,ttype);
  664.  
  665.             prog = strtok(tt," ");
  666.             args = strtok(NULL," ");
  667.  
  668.             prdebug("Starting shell program \"%s\" (parameters: \"%s\")\n",prog,args?args:(STRPTR)"<none>");
  669.  
  670.             if(SystemTags(prog,
  671.                                 NP_Arguments,args,
  672.                                 SYS_Asynch,TRUE,
  673.                                 TAG_DONE) != RETURN_OK)
  674.             {
  675.                 prdebug("Error starting program!\n");
  676.             }
  677.             FreeVecPooled(Config->mc_MemPool,tt);
  678.         }
  679.     }
  680. }
  681.  
  682. static BOOL ExistsIcon(STRPTR prog)
  683. {
  684. STRPTR icon;
  685. ULONG proglen;
  686. BOOL ret = FALSE;
  687.  
  688.     proglen = strlen(prog);
  689.     if(icon = AllocVecPooled(Config->mc_MemPool,proglen+6))
  690.     {
  691.     BPTR lock;
  692.  
  693.         strcpy(icon,prog);
  694.         strcpy(icon+proglen,".info");
  695.         if(lock = Lock(icon,ACCESS_READ))
  696.         {
  697.             UnLock(lock);
  698.             ret = TRUE;
  699.         }
  700.         FreeVecPooled(Config->mc_MemPool,icon);
  701.     }
  702.     return ret;
  703. }
  704.  
  705. /*************************************************************************/
  706.  
  707. static STRPTR FindConfigFile(void)
  708. {
  709. static STRPTR CfgAlts[3] = {NULL,"PROGDIR:MRQ.config","s:MRQ.config"};
  710. BPTR lock;
  711. int i;
  712.  
  713.     i = (CfgAlts[0] = ttVars.ConfigName) ? 0 : 1;
  714.     for(; i<(sizeof(CfgAlts)/sizeof(STRPTR)); i++)
  715.     {
  716.         if(lock=Lock(CfgAlts[i],ACCESS_READ))
  717.         {
  718.             UnLock(lock);
  719.             return CfgAlts[i];
  720.         }
  721.     }
  722.     return NULL;
  723. }
  724.  
  725. static BOOL CheckDir(STRPTR dir)
  726. {
  727. BPTR lock;
  728. BOOL ret=FALSE;
  729.  
  730.     if(lock=Lock(dir,ACCESS_READ))
  731.     {
  732.     struct FileInfoBlock *fib;
  733.         if(fib = AllocDosObjectTagList(DOS_FIB,NULL))
  734.         {
  735.             if(Examine(lock,fib))
  736.             {
  737.                 if(fib->fib_DirEntryType > 0) ret=TRUE;    // entry is directory
  738.             }
  739.             FreeDosObject(DOS_FIB,fib);
  740.         }
  741.         UnLock(lock);
  742.     }
  743.     return ret;
  744. }
  745.  
  746. static BOOL AskQuit(void)
  747. {
  748.  
  749.     if(CheckPatchManager()) return TRUE;    // don't ask if it's safe to remove patches
  750.  
  751.     if(ttVars.AfterPatch)
  752.     {
  753.         MUI_RequestA(Application,NULL,0,"MRQ Error","*:-(",
  754.             "MRQ has started another program after patching!\n"
  755.             "Therefore it can't be unloaded without causing\n"
  756.             "a certain crash on the next call to a patched function.",NULL);
  757.         return FALSE;
  758.     }
  759.     return (BOOL)MUI_RequestA(Application,NULL,0,"MRQ Warning","_I am sure|*_Not really",
  760.                         "Are you sure you want to quit MRQ?\n"
  761.                         "This is not safe if other programs have\n"
  762.                         "patched the same functions!",NULL);
  763. }
  764.  
  765. static BOOL CheckPatchManager(void)
  766. {
  767. BOOL ret;
  768.  
  769.     Forbid();
  770.     ret = (BOOL)(FindPort("SetMan"));
  771.     Permit();
  772.     return ret;
  773. }
  774.  
  775. static BOOL CreateCustomClasses(void)
  776. {
  777.     if(MUIMRQWindowClass = NewMRQWindowClass())
  778.     {
  779.         MRQWindowClass = MUIMRQWindowClass->mcc_Class;
  780.         return TRUE;
  781.     }
  782.     DeleteCustomClasses();
  783.     return FALSE;
  784. }
  785.  
  786. static void DeleteCustomClasses(void)
  787. {
  788.     if(MUIMRQWindowClass)    MUI_DeleteCustomClass(MUIMRQWindowClass);
  789. }
  790.  
  791.  
  792.  
  793. void prdebug(char *fmt, ...)
  794. {
  795. va_list arglist;
  796. char tbuf[768];
  797.  
  798.     if(ttVars.Debug)
  799.     {
  800.         memset(tbuf,0,sizeof(tbuf));
  801.         va_start(arglist,fmt);
  802.         mb_VNSPrintf(tbuf,fmt,sizeof(tbuf),(LONG*)arglist);
  803.         FPuts(_debugfh,tbuf);
  804.         va_end(arglist);
  805.     }
  806. }
  807. @
  808.  
  809.  
  810. 1.3
  811. log
  812. @Disabled DOS requesters for MRQ's main process to avoid deadlocks
  813. @
  814. text
  815. @d9 1
  816. a9 1
  817. /* $Id: mrq.c 1.2 2000/01/25 17:28:05 msbethke Exp msbethke $
  818. d12 3
  819. d35 1
  820. a35 1
  821. #include <MUI/NewImage_mcc.h>
  822. d91 1
  823. a91 1
  824. const UBYTE VersionString[]="$VER: MRQ 2.0b3 by M.Bethke (16.02.2000)";
  825. d202 3
  826. a204 3
  827.         (ttVars.Quality==MUIV_NewImage_Quality_Best)?"Best":
  828.         (ttVars.Quality==MUIV_NewImage_Quality_Medium)?"Medium":
  829.         (ttVars.Quality==MUIV_NewImage_Quality_High)?"High":
  830. d574 3
  831. a576 3
  832.         if(!stricmp(s,"best")) return MUIV_NewImage_Quality_Best;
  833.         if(!stricmp(s,"high")) return MUIV_NewImage_Quality_High;
  834.         if(!stricmp(s,"low")) return MUIV_NewImage_Quality_Low;
  835. d578 1
  836. a578 1
  837.     return MUIV_NewImage_Quality_Medium;        // default
  838. d608 1
  839. a608 1
  840.                 }
  841. @
  842.  
  843.  
  844. 1.2
  845. log
  846. @Adapted to new header names
  847. @
  848. text
  849. @d9 1
  850. a9 1
  851. /* $Id: mrq.c 1.1 2000/01/25 16:43:18 msbethke Exp msbethke $
  852. d12 3
  853. d88 1
  854. a88 1
  855. const UBYTE VersionString[]="$VER: MRQ 1.13 by M.Bethke (25.01.2000)";
  856. d112 3
  857. a114 1
  858. static UBYTE MRQRendezvousPort[] = "MRQ.Rendezvous";
  859. a115 1
  860.  
  861. d118 5
  862. a122 1
  863.     if(FindPort(MRQRendezvousPort))
  864. d217 1
  865. a217 1
  866.                 MainPort->mp_Node.ln_Name = MRQRendezvousPort;
  867. d404 3
  868. @
  869.  
  870.  
  871. 1.1
  872. log
  873. @Initial revision
  874. @
  875. text
  876. @d9 5
  877. a13 1
  878. /* $Id:$
  879. a14 1
  880. ** $Log:$
  881. d36 1
  882. a36 1
  883. #include "mrq_config.h"
  884. d39 1
  885. a39 1
  886. #include "MUI_ERA.h"
  887. @
  888.